package mysql

import (
	"data-transfer/conf"
	"data-transfer/plugins"
	"data-transfer/plugins/mysql/session"
	"github.com/go-mysql-org/go-mysql/canal"
	driver "github.com/go-sql-driver/mysql"
	"xorm.io/xorm"
)

const (
	// 插件的名称，这里是 MySQL
	PluginName = "mysql"
)

// 针对mysql 的 数据源插件
type plugin struct {
}

// Init 初始化默认插件
func InitPlugin() {
	plugins.RegisterPlugin(PluginName, &plugin{})
}

//校验接口实现
var _ plugins.Plugin = (*plugin)(nil)

// CreateDB 初始化DB对象,根据DBKind 来创建 Source,Target 或gocanal的数据源
// dbKind ---> dbName
func (p *plugin) CreateDB(dbKind plugins.DbKind, cfg *conf.DbConfig) (plugins.DB, error) {

	var canalErr error
	goCanal := new(canal.Canal)
	dataBaseName := ""
	switch dbKind {
	case plugins.DbKindSource:
		dataBaseName = plugins.DbNameSource
	case plugins.DbKindTarget:
		dataBaseName = plugins.DbNameTarget
	case plugins.DbKindCanal:
		dataBaseName = plugins.DbNameCanal
		dbConfInfo, _ := cfg.DB[dataBaseName]
		addr := dbConfInfo.ConnectAddr
		conf, _ := driver.ParseDSN(addr)
		canalConf := canal.NewDefaultConfig()
		canalConf.Addr = conf.Addr
		canalConf.User = conf.User
		canalConf.Password = conf.Passwd
		canalConf.Dump.TableDB = conf.DBName
		canalConf.Dump.Tables = cfg.MonitorTables
		canalConf.Dump.ExecutionPath = cfg.MysqlDumpExecutionPath
		goCanal, canalErr = canal.NewCanal(canalConf)
	case plugins.DbKindInfoService:
		dataBaseName = plugins.DbNameInfoService
	}

	if canalErr != nil {
		return nil, canalErr
	}
	conn, err := p.createDBConnection(cfg, dataBaseName)
	if err != nil {
		return nil, err
	}

	db := newDB(dbKind, dataBaseName, conn, goCanal)
	return db, nil
}

// createDBConnection 创建数据库连接
func (p *plugin) createDBConnection(cfg *conf.DbConfig, dbName string) (*xorm.Engine, error) {
	mysqlSession, err := session.NewSession(cfg, dbName)
	if err != nil {
		return nil, err
	}
	return mysqlSession.Engine, nil
}
